import random
from flask import Flask,Blueprint,request,make_response,Response
from model.model import *
from catch import redis_cli
import string,re,json,redis,time
# from tools.tools import create_img
from captcha.image import ImageCaptcha
from utils.tasks.send_sms_code import send_one_code
from threading import Thread
from tools.tools import my_router,item2dict
from flask_login import login_user,login_required,logout_user,current_user
from config import MOBILE_IMG_CODE_KEY,REDIS_MSG_CODE_KEY,MD5_SALT
import os
from hashlib import md5
from swager_init import siwa
from flask_siwadoc import BaseModel
from kafka_init import producer,consumer,kafka_cli
from kafka import KafkaConsumer

user = Blueprint('/user',__name__)

class RegisterJson(BaseModel):
    name:str
    password:str
    mobile:str
    img:str
    landlord:bool = Flask
    code:str
@user.route('/register',methods=['post'])
@siwa.doc(tags=['user'],body=RegisterJson)
def register():
    data = request.json
    code = data.pop('code')
    mobile = data.get('mobile')
    if not mobile:
        return my_router(207)
    data['password'] = md5(data['password'].encode() + MD5_SALT).hexdigest()
    data['password'] = md5(data['password'].encode()+MD5_SALT).hexdigest()
    code1 = redis_cli.get(MOBILE_IMG_CODE_KEY + mobile).decode('utf-8')
    if not code1:
        return my_router(405)
    if code.lower() != code1.decode('utf-8').lower():
        return my_router(204)
    if User.query.filter_by(mobile=mobile).first():
        return my_router(408)
    db.session.add(User(**data))
    db.session.commit()
    redis_cli.delete(REDIS_MSG_CODE_KEY + mobile)
    redis_cli.delete(MOBILE_IMG_CODE_KEY + mobile)
    return my_router(200)

# 登录
@user.route('/login',methods=['post'])
def user_login():
    mobile = request.form.get('mobile')
    pwd = request.form.get('password')
    user = User.query.filter_by(mobile=mobile).first()
    if user and user.password == md5(pwd.encode()+MD5_SALT).hexdigest():
        login_user(user)
        return my_router(200,item2dict(user))
    return my_router(206)

# 退出
@user.route('/login_out',methods=['get'])
@login_required
def user_out():
    print(current_user)
    logout_user()
    return my_router(200)

# 聊天
# 轮询就是实时得到某个数据就会一致获取某个数据，一般是由客户端
# 向服务端发出一个设置较长网络超时时间的 HTTP 请求，并在Http
# 连接超时前，不主动断开连接；待客户端超时或有数据返回后，再次
# 建立一个同样的Http请求，重复以上过程 。
@user.route('/send_chat',methods=['post'])
@login_required
def send_chat():
    msg = request.json.get('msg').encode('utf-8')
    topic = request.args.get('topic')
    producer.send(topic,msg)
    return my_router(200)

# 获取
@user.route('/read_chat',methods=['get'])
@login_required
def read_chat():
    topic = request.args.get('topic')
    consumer = KafkaConsumer(topic,group_id='chat')
    value = next(consumer).value.decode('utf-8')
    consumer.close()
    return my_router(200,{'data':value})

# 后台的获取聊天
@user.route('/chat/back',methods=['get'])
@login_required
def chat_back():
    topic = request.args.get('topic')
    consumer = KafkaConsumer(topic,group_id='back')
    value = next(consumer).value.decode('utf-8')
    consumer.close()
    return my_router(200,{'data':value})

# # 分组
@user.route('/chat/group',methods=['post'])
@login_required
def add_topic():
    send_id = request.args.get('send_id')
    topic = '_'.join(sorted([send_id, str(current_user.id)]))
    producer.send(topic,b'')
    return my_router(200,data={'topic':topic})

@user.route('/imgcode/<string:mobile>',methods=['get'])
def get_imgcode(mobile):
    # mobile = request.args.get('mobile')
    # code = [string.ascii_lowercase[randint(0,27)] for _ in range(4)]
    # img = create_img(code)
    # catch.set(f'code_{mobile}',''.join(code))
    # with open(img,'rb') as f:
    #     response = Response(f.read(),mimetype='image/jpeg')
    # return respon
    if not mobile:
        return {'msg':'前端数据不完整','code':400}
    if not re.findall(r'^1[3-9]\d{9}$',mobile):
        return {'msg':'手机号格式不对','code':400}
    img_code = ''.join(random.sample(string.ascii_letters + string.digits,4))
    cap = ImageCaptcha()
    img = cap.generate(img_code)
    redis_cli.set(mobile, img_code,ex=120)
    return Response(img)

# 校验短信验证码
@user.route('/sms',methods=['get'])
def message():
    mobile = request.args.get('mobile')
    if not mobile:
        return {'msg':'前端数据不完整','code':400}
    if not re.findall(r'^1[3-9]\d{9}$',mobile):
        return {'msg':'手机号格式不对','code':400}
    Thread(target=send_one_code,args=(mobile,)).start()
    return my_router(200)
    # mobile = request.args.get('mobile')
    # # celery 异步任务
    # if not mobile:
    #     return Response({'msg': '前端数据不完整', 'code': 400})
    # if not re.search(r'^1[3-9]\d{9}$', mobile):
    #     return Response({'msg': '手机号格式不对', 'code': 401})
    # sms_code = random.randint(100000, 999999)
    # rds = send_one_code.delay(mobile, sms_code)
    # cli = redis.Redis(db=5)
    # time.sleep(3)
    # print('>>>>>>>>>>>>>>>..', rds)
    # key = 'celery-task-meta-' + rds.id
    # rds_data = cli.get(key).decode()
    # print('>>>>>>>>>>>>>>>>>>>>>',rds_data)
    # rds_status = json.loads(json.loads(rds_data)['result'])['statusCode']
    # if rds_status == '000000' or rds_status == '112310':
    #     cli = redis.Redis(db=2)
    #     cli.setex(f'sms_{mobile}', 120, sms_code)
    #     cli.close()
    #     return {'msg': "验证码发送成功，请接收!", 'code': 200}
    # else:
    #     return {'msg': '验证码发送失败', 'code': 400}
    #   #获取短信验证码
    #   #容联云
    # # 删除redis中的短信验证码
    # # catch.delete(f'code_{mobile}')
    # # return {'msg':'ok','code':200}

    # mobile = request.args.get('mobile')
    # if not mobile:
    #     return {'code': 400, 'msg': '字段不完整'}
    # # 生成验证码
    # data = random.randint(1000, 9999)
    # # 发送验证码
    # resp = send_one_code.delay(mobile, data)
    # print('>>>>>>>>>>',resp)
    # # 睡眠时间
    # time.sleep(1)
    # resp_data = 'celery-task-meta-' + resp.id
    # print('??????????????',resp_data)
    # # 存放数据库
    # cli = redis.Redis(db=6)
    # red = cli.get(resp_data).decode()
    # print('>>>>>>>>>>>>>>',red)
    # red_data = json.loads(red)['result']
    # reds = json.loads(red_data)['statusCode']
    # print('>>>>>>>>>>>>>>>>',reds)
    # if reds == '000000' or reds == '112310':
    #     cli.setex(f'sms_code:{mobile}', 120, data)
    #     return {'code': 200, 'msg': '发送成功'}
    # else:
    #     return {'code': 500, 'msg': '发送失败'}

@user.route('/get_user_info',methods=['get'])
def get_user_info():
    uid = request.args.get('uid')
    if not uid:
        return my_router(409)
    user = User.query.filter_by(id = uid).first()
    if not user:
        return my_router(208)
    user_list = []
    for i in user:
        user_list.append({
            'id':i.id,
            'login_time':i.login_time,
            'mobile':i.mobile
        })
    return {'msg':'ok','code':200,'data':user_list}

# 获取用户信息
@user.route('/info',methods=['get'])
@login_required
def info():
    return my_router(200, item2dict(current_user,filter=['password']))
    # uid = request.args.get('uid')
    # if not uid:
    #     return my_router(409)
    # user = User.query.filter_by(id = uid).first()
    # if not user:
    #     return my_router(208)
    # user_list = []
    # for i in user:
    #     user_list.append({
    #         'id':i.id,
    #         'login_time':i.login_time,
    #         'mobile':i.mobile
    #     })
    # return {'msg':'ok','code':200,'data':user_list}

# 修改用户的信息
@user.route('/update_user/<int:uid>',methods=['put'])
def put_user_info(uid):
    info = request.json
    User.query.filter_by(id=uid).update(info)
    db.session.commit()
    return my_router(200)

# 上传头像
@user.route('/avatar',methods=['post'])
def avatar():
    img = request.files.get('img')
    uid = request.form.get('uid')
    # 判断新路径存在不存在，不存在就创建新的路径
    file_path = f'./static/images/{uid}'
    if not os.path.exists(file_path):
        os.mkdir(path=file_path)
    # 数据库更新
    img.save(f'{file_path}/{img.filename}')
    User.query.filter_by(id=uid).update({'img':img.filename})
    db.session.commit()
    return my_router(200)

# 更新上传数据
@user.route('/av',methods=['post'])
def duan_dian_avatar():
    data = request.json
    # 判断新路径存在不存在，不存在就创建新的路径
    file_path = f'./static/images/{data.get("uid")}'
    if not os.path.exists(file_path):
        os.mkdir(path=file_path)
    with open(os.path.join(file_path,f'{data["bytes_change"] + data["file_name"]}'),'wb') as f:
        f.write(data['data'].encode('utf-8'))
    if data['max_change'] == int(data['bytes_change'].split('-')[-1]):
        dirs = os.listdir(file_path)
        dirs.sort()
        for f_name in dirs:
            old_file_path = os.path.join(file_path,f_name)
            if data['file_name'] in f_name:
                with open(os.path.join(file_path,data['file_name']),'ab') as f:
                    old_file = open(old_file_path,'rb')
                    f.write(old_file.read())
                old_file.close()
                #删除旧文件
                os.remove(old_file_path)
    return my_router(200)

# 获取文件
@user.route('/avatar',methods=['get'])
def get_avatar():
    data = request.json
    # 判断新路径存在不存在，不存在就创建新的路径
    file_path = f'./static/images/{data.get("uid")}'
    dirs = os.listdir(file_path)
    filter(lambda x: data['file_name'] in x,dirs)
    return dirs
